//现成的应用场景
/*
线程的应用场景则更适用于需要并发执行任务的场景。例如，
在图形界面应用程序、多媒体处理和数据处理等应用中，
线程可以共享进程的地址空间和资源，使得数据共享和通信更加高效。
使用线程可以减少程序的复杂，提高程序的响应速度和效率。
*/


#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

// 创建线程的id号
pthread_t play_game_pt;
pthread_t watch_tv_pt;
pthread_t listen_to_music_pt;

void clear_routine(void* arg)
{

}

void* play_game(void*arg)
{
    //功能区
    while (1)
    {
        
    }
    // 线程的退出 // 通知系统，赶紧给线程收尸
    pthread_exit(NULL);
}

// 看电视
void* watch_tv(void* arg)
{
    // 1、将自身设置为分离属性(此线程函数结束后，自动有人给它收尸)
    pthread_detach(pthread_self());     // pthread_self函数可以获取自己的线程id
    int count = (int *)arg;   //传参调用
    //功能区
    while (1)
    {

        // 注册一个取消处理函数
        pthread_cleanup_push(clear_routine, NULL);

        while(1)
        {
            //代码区
        }
         // 注册一个取消处理函数
        pthread_cleanup_pop(0);     // 正常结束的时候，不执行
        // pthread_cleanup_pop(1);  // 正常结束的时候，执行
    }
    // 线程的退出(通知系统，赶紧回收线程资源(没多大用))
    pthread_exit(NULL);
}

// 听音乐
void* listen_to_music(void* arg)
{

    int count = 0;
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);    //关闭取消请求
    while (1)
    {
        //不可以被主函数信号杀死（工作状态）
    }
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);     //开启取消请求
    while (1)
    {
        //摸鱼状态
    }
    // 线程的退出(通知系统，赶紧回收线程资源(没多大用))
    pthread_exit(NULL);
}


int main(int argc, char const *argv[])
{
    // 1、初始化线程属性 
    pthread_attr_t attr;
    pthread_attr_init(&attr);  
    // 2、设置线程属性 (分离属性) (此线程函数结束后，自动有人给它收尸)
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
    // 1、线程的创建
    int number=0;
    pthread_create(&play_game_pt,  &attr, play_game, NULL);  //设置分离属性启动

    pthread_create(&watch_tv_pt,  NULL, watch_tv,  (void *)&number); //传参调用

    pthread_create(&listen_to_music_pt,  NULL, listen_to_music, NULL);


    // 2、线程资源的回收
    pthread_join(play_game_pt, NULL);           // 当线程函数退出，那么此函数为其收尸(等你死，给你收尸)
    pthread_join(watch_tv_pt, NULL);
    pthread_join(listen_to_music_pt, NULL);
   

    // 注意：线程是在进程上的，进程一旦结束，在进程上的所有线程也都会死亡！！！
    getchar();

    return 0;
}
